﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Library.Models;

namespace Library.MVCHelpers
{
    public static class SEOHelper
    {
        #region URL Dictionary

        public static Dictionary<string, URLInfo> URLDictionary;

        public static void RegisterUrlDictionary()
        {
            URLDictionary = new Dictionary<string, URLInfo>(StringComparer.OrdinalIgnoreCase);

            using (var db = new EcommerceEntities())
            {
                var products = db.Products;
                foreach (var product in products)
                {
                    // Register product URLs
                    foreach (var productCulture in product.ProductCultures)
                    {
                        URLInfo temp;
                        if (!URLDictionary.TryGetValue(productCulture.Url, out temp))
                        {
                            URLDictionary.Add(productCulture.Url, new URLInfo(URLTypes.Product, product.Id));
                        }
                    }

                    // Register product category URLs
                    var productCategoryCultures = product.ProductCategory.ProductCategoryCultures;
                    foreach (var productCategoryCulture in productCategoryCultures)
                    {
                        URLInfo temp;
                        if (!URLDictionary.TryGetValue(productCategoryCulture.Url, out temp))
                        {
                            URLDictionary.Add(productCategoryCulture.Url, new URLInfo(URLTypes.ProductCategory, productCategoryCulture.ProductCategoryId));
                        }

                        // Register brand URL
                        var brandCulture = product.Brand.BrandCultures.SingleOrDefault(i => i.Culture == productCategoryCulture.Culture);
                        if (brandCulture != null)
                        {
                            if (productCategoryCulture.Culture == "vi-vn")
                            {
                                var brandUrl1 = productCategoryCulture.Url + "-" + brandCulture.Url;
                                if (!URLDictionary.TryGetValue(brandUrl1, out temp))
                                {
                                    URLDictionary.Add(brandUrl1, new URLInfo(URLTypes.Brand, brandCulture.BrandId));
                                }
                            }
                            else
                            {
                                var brandUrl2 = brandCulture.Url + "-" + productCategoryCulture.Url;
                                if (!URLDictionary.TryGetValue(brandUrl2, out temp))
                                {
                                    URLDictionary.Add(brandUrl2, new URLInfo(URLTypes.Brand, brandCulture.BrandId));
                                }
                            }
                        }
                    }
                }
            }
        }

        public static URLInfo GetURLInfo(string url)
        {
            if (URLDictionary == null || string.IsNullOrWhiteSpace(url))
            {
                return null;
            }

            URLInfo temp;
            if (URLDictionary.TryGetValue(url, out temp))
            {
                return temp;
            }

            return null;
        }

        public static bool UrlIsExists(string url)
        {
            return GetURLInfo(url) != null;
        }

        public static void RegisterUrl(string newUrl, URLInfo urlInfo)
        {
            try
            {
                if (!UrlIsExists(newUrl))
                {
                    URLDictionary.Add(newUrl, urlInfo);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex);
            }
        }

        public static void UpdateUrl(string oldUrl, string newUrl, URLInfo urlInfo)
        {
            try
            {
                if (!UrlIsExists(newUrl))
                {
                    URLDictionary.Remove(oldUrl);
                    URLDictionary.Add(newUrl, urlInfo);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex);
            }
        }        

        #endregion

        public static string GetMenuUrl(Menu menu)
        {
            if (string.IsNullOrEmpty(menu.Url))
            {
                return null;
            }

            if (menu.Culture == Settings.DefaultCulture)
            {
                return menu.Url.ToLower();
            }
            return menu.Culture.ToLower() + "/" + menu.Url.ToLower();
        }

        public static string ToURL(this string phrase)
        {
            string str = phrase.ToUnsignedVietnamese().RemoveAccent().ToLower();

            str = Regex.Replace(str, @"[^a-z0-9\s-]", ""); // invalid chars           
            str = Regex.Replace(str, @"\s+", " ").Trim(); // convert multiple spaces into one space   
            str = str.Substring(0, str.Length <= 45 ? str.Length : 45).Trim(); // cut and trim it   
            str = Regex.Replace(str, @"\s", "-"); // hyphens   

            return str;
        }

        public static string RemoveAccent(this string txt)
        {
            byte[] bytes = Encoding.GetEncoding("Cyrillic").GetBytes(txt);
            return Encoding.ASCII.GetString(bytes);
        }

        public static string ToUnsignedVietnamese(this string vietnamese)
        {
            const string findText = "áàảãạâấầẩẫậăắằẳẵặđéèẻẽẹêếềểễệíìỉĩịóòỏõọôốồổỗộơớờởỡợúùủũụưứừửữựýỳỷỹỵÁÀẢÃẠÂẤẦẨẪẬĂẮẰẲẴẶĐÉÈẺẼẸÊẾỀỂỄỆÍÌỈĨỊÓÒỎÕỌÔỐỒỔỖỘƠỚỜỞỠỢÚÙỦŨỤƯỨỪỬỮỰÝỲỶỸỴ";
            const string replText = "aaaaaaaaaaaaaaaaadeeeeeeeeeeeiiiiiooooooooooooooooouuuuuuuuuuuyyyyyAAAAAAAAAAAAAAAAADEEEEEEEEEEEIIIIIOOOOOOOOOOOOOOOOOUUUUUUUUUUUYYYYY";
            int index = -1;
            char[] arrChar = findText.ToCharArray();
            while ((index = vietnamese.IndexOfAny(arrChar)) != -1)
            {
                int index2 = findText.IndexOf(vietnamese[index]);
                vietnamese = vietnamese.Replace(vietnamese[index], replText[index2]);
            }
            return vietnamese;
        }

        public class URLInfo
        {
            public URLInfo(URLTypes urlType, int modelId)
            {
                URLType = urlType;
                ModelId = modelId;
            }

            public URLTypes URLType { get; set; }
            public int ModelId { get; set; }
        }
    }
}
